<!DOCTYPE html>
<html lang="en">

<!-- Head tag (contains Google-Analytics、Baidu-Tongji)-->
<head>
  <!-- Google Analytics -->
  

  <!-- Baidu Tongji -->
  
    <script type="text/javascript">
      // Originial
      var _hmt = _hmt || [];
      (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?cdf616a127124dd7ff798963125b304d";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script>
  

  <!-- Baidu Push -->
  
    <script>
      (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
          bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
          bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
      })();
    </script>
  

  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>

  <meta name="google-site-verification" content="lxDfCplOZbIzjhG34NuQBgu2gdyRlAtMB4utP5AgEBc"/>
  <meta name="baidu-site-verification" content="PpzM9WxOJU"/>

  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="description" content="It&#39;s an IT blog..."/>
  <meta name="keyword" content="zhuang,IT  blog,Blog"/>
  <link rel="shortcut icon" href="/img/avatar/java-head.png"/>

  <!-- Place this tag in your head or just before your close body tag. -->
  <script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script>

  
    <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css"/>

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/beantech.min.css"/>

    <!-- Pygments Highlight CSS -->
    <link rel="stylesheet" href="/css/highlight.css"/>
    <link rel="stylesheet" href="/css/widget.css"/>
    <link rel="stylesheet" href="/css/rocket.css"/>
    <link rel="stylesheet" href="/css/signature.css"/>
    <link rel="stylesheet" href="/css/catalog.css"/>
    <link rel="stylesheet" href="/css/livemylife.css"/>

    
      <!-- wave start -->
      <link rel="stylesheet" href="/css/wave.css"/>
      <!-- wave end -->
    

    
      <!-- top start (article top hot config) -->
      <link rel="stylesheet" href="/css/top.css"/>
      <!-- top end -->
    

    
      <!-- ThemeColor start -->
      <link rel="stylesheet" href="/css/scroll.css"/>
      <!-- ThemeColor end -->
    

    
      <!-- viewer start (Picture preview) -->
      <link rel="stylesheet" href="/css/viewer.min.css"/>
      <!-- viewer end -->
    

    
      <!-- Search start -->
      <link rel="stylesheet" href="/css/search.css"/>
      <!-- Search end -->
    

    
      <!-- ThemeColor start -->
      <link rel="stylesheet" href="/css/themecolor.css"/>
      <!-- ThemeColor end -->
    

    

    
  

  <!-- Custom Fonts -->
  <!-- <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
  <!-- Hux change font-awesome CDN to qiniu -->
  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.5.0/css/font-awesome.min.css" type="text/css">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

  <!-- Hux Delete, sad but pending in China <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'> <link
  href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/ css'> -->

  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]-->

  <!-- ga & ba script hoook -->
  <link rel="canonical" href="http://yoursite-url/cn/面试/面试复习/">
  <title>
    
      面试总复习（一） - either thin | or die
    
  </title>
<meta name="generator" content="Hexo 5.4.0"></head>


<!-- hack iOS CSS :active style -->

	<body ontouchstart="" class="body--light body--dark">


		<!-- ThemeColor -->
		
		<!-- ThemeColor -->
<style type="text/css">
  .body--light {
    --light-mode: none;
    --dark-mode: block;
  }
  .body--dark {
    --light-mode: block;
    --dark-mode: none;
  }
  i.mdui-icon.material-icons.light-mode {
    display: var(--light-mode);
  }
  i.mdui-icon.material-icons.dark-mode {
    display: var(--dark-mode);
  }
</style>
<div class="toggle" onclick="document.body.classList.toggle('body--dark')">
  <i class="mdui-icon material-icons light-mode"></i>
  <i class="mdui-icon material-icons dark-mode"></i>
</div>
<script>
  //getCookieValue
  function getCookieValue(a) {
    var b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)');
    return b
      ? b.pop()
      : '';
  }
  let themeMode = 'dark';
  if (getCookieValue('sb-color-mode') && (getCookieValue('sb-color-mode') !== themeMode)) {
    let dbody = document.body.classList;
    themeMode === 'dark' ? dbody.remove('body--dark') : dbody.add('body--dark');
  }

  //setCookieValue
  var toggleBtn = document.querySelector(".toggle");
  toggleBtn.addEventListener("click", function () {
    var e = document.body.classList.contains("body--dark");
    var cookieString = e
      ? "dark"
      : "light";
    var exp = new Date();
    exp.setTime(exp.getTime() + 3 * 24 * 60 * 60 * 1000); //3天过期
    document.cookie = "sb-color-mode=" + cookieString + ";expires=" + exp.toGMTString() + ";path=/";
  });
</script>

		

		<!-- Gitter -->
		

		<!-- Navigation (contains search)-->
		<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header page-scroll">
      <button type="button" class="navbar-toggle">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="/">平平淡淡</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <!-- Known Issue, found by Hux: <nav>'s height woule be hold on by its content. so, when navbar scale out, the <nav> will cover tags. also mask any touch event of tags, unfortunately. -->
    <div id="huxblog_navbar">
      <div class="navbar-collapse">
        <ul class="nav navbar-nav navbar-right">
          <li>
            <a href="/">首页</a>
          </li>

          
          
          
          
          <li>
            <a href="/archive/">
              
              归档
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/tags/">
              
              标签
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/categories/">
              
              分类
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/about/">
              
              关于
              
              
            </a>
          </li>
          
          

          
          <li>
            <a class="popup-trigger">
              <span class="search-icon"></span>搜索</a>
          </li>
          

          <!-- LangSelect -->
          
        </ul>
      </div>
    </div>
    <!-- /.navbar-collapse -->
  </div>
  <!-- /.container -->
</nav>
<!-- progress -->
<div id="progress">
  <div class="line" style="width: 0%;"></div>
</div>

<script>
  // Drop Bootstarp low-performance Navbar Use customize navbar with high-quality material design animation in high-perf jank-free CSS3 implementation
  var $body = document.body;
  var $toggle = document.querySelector('.navbar-toggle');
  var $navbar = document.querySelector('#huxblog_navbar');
  var $collapse = document.querySelector('.navbar-collapse');

  $toggle.addEventListener('click', handleMagic)

  function handleMagic(e) {
    if ($navbar.className.indexOf('in') > 0) {
      // CLOSE
      $navbar.className = " ";
      // wait until animation end.
      setTimeout(function() {
        // prevent frequently toggle
        if ($navbar.className.indexOf('in') < 0) {
          $collapse.style.height = "0px"
        }
      }, 400)
    } else {
      // OPEN
      $collapse.style.height = "auto"
      $navbar.className += " in";
    }
  }
</script>


		<!-- Post Header (contains intro-header、signature、wordcount、busuanzi、waveoverlay) -->
		<!-- Modified by Yu-Hsuan Yen -->
<!-- Post Header -->

  <style type="text/css">
    .body--light {
      /* intro-header */
      --intro-header-background-image-url-home: url('/img/header_img/home_bg1.jpg');
      --intro-header-background-image-url-post: url('/img/header_img/lml_bg.jpg');
      --intro-header-background-image-url-page: url('//img/header_img/lml_bg.jpg');
    }
    .body--dark {
      --intro-header-background-image-url-home: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('/img/header_img/home_bg1.jpg');
      --intro-header-background-image-url-post: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('/img/header_img/lml_bg.jpg');
      --intro-header-background-image-url-page: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('//img/header_img/lml_bg.jpg');
    }

    header.intro-header {
       /*post*/
        background-image: var(--intro-header-background-image-url-post);
        /* background-image: url('/img/header_img/lml_bg.jpg'); */
      
    }

    
      #signature {/*signature*/
        background-image: url('/img/signature/signature.png');
      }
    
  </style>





<header class="intro-header">
  <!-- Signature -->
  <div id="signature">
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
          
          <div class="post-heading">
            <div class="tags">
              
              <a class="tag" href="/tags/#java" title="java">java</a>
              
              <a class="tag" href="/tags/#面试" title="面试">面试</a>
              
            </div>
            <h1>面试总复习（一）</h1>
            <h2 class="subheading"></h2>
            <span class="meta">
              Posted by zhuang on
              2020-03-10
            </span>


            
            <!-- WordCount start -->
            <div class="blank_box"></div>
            <span class="meta">
              Estimated Reading Time <span class="post-count">20</span> Minutes
            </span>
            <div class="blank_box"></div>
            <span class="meta">
              Words <span class="post-count">5.3k</span> In Total
            </span>
            <div class="blank_box"></div>
            <!-- WordCount end -->
            
            
            <!-- 不蒜子统计 start -->
            <span class="meta" id="busuanzi_container_page_pv">
              Viewed <span id="busuanzi_value_page_pv"><i class="fa fa-spinner fa-spin"></i></span> Times
            </span>
            <!-- 不蒜子统计 end -->
            


          </div>
          
        </div>
      </div>
    </div>
  </div>

  
  <!-- waveoverlay start -->
  <div class="preview-overlay">
    <svg class="preview-waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
      <defs>
        <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"></path>
      </defs>
      <g class="preview-parallax">
        <use xlink:href="#gentle-wave" x="48" y="0" fill=var(--gentle-wave1)></use>
        <use xlink:href="#gentle-wave" x="48" y="3" fill=var(--gentle-wave2)></use>
        <use xlink:href="#gentle-wave" x="48" y="5" fill=var(--gentle-wave3)></use>
        <use xlink:href="#gentle-wave" x="48" y="7" fill=var(--gentle-wave)></use>
      </g>
    </svg>
  </div>
  <!-- waveoverlay end -->
  

</header>



		<!-- Main Content (Post contains
	Pager、
	tip、
	socialshare、
	gitalk、gitment、disqus-comment、
	Catalog、
	Sidebar、
	Featured-Tags、
	Friends Blog、
	anchorjs、
	) -->
		<!-- Modify by Yu-Hsuan Yen -->
<!-- Post Content -->
<article>
  <div class="container">
    <div class="row">
      <!-- Post Container -->
      <div class="col-lg-8 col-lg-offset-1 col-md-10 col-md-offset-1 post-container">

        <h2 id="第一章-JavaSE基础"><a href="#第一章-JavaSE基础" class="headerlink" title="第一章 JavaSE基础"></a>第一章 JavaSE基础</h2><h3 id="一、Java面向对象"><a href="#一、Java面向对象" class="headerlink" title="一、Java面向对象"></a>一、Java面向对象</h3><h4 id="1-面向对象特性以及对这些特性的理解"><a href="#1-面向对象特性以及对这些特性的理解" class="headerlink" title="1.面向对象特性以及对这些特性的理解"></a>1.面向对象特性以及对这些特性的理解</h4><ul>
<li>继承：继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类（超类。基类）；得到继承信息的类被称为子类（派生类）。</li>
<li>封装：封装是把数据和操作数据的方法绑定起来，对数据的访问只能通过已定义的接口。封装就是隐藏一切可隐藏的东西，只向外界提供最简单的编程接口。</li>
<li>多态性：多态性是指允许不同子类型的对象对同一消息作出不同的响应。多态性分为编译时的多态性和运行时的多态性。方法重载（overload）实现的是编译时的多态性（前绑定），而方法重写（override）实现的是运行时的多态性（后绑定）。运行时的多态是面向对象最精髓的东西，要实现多态需要做两件事：1.方法重写（子类继承父类并重写父类中已有的或抽象的方法）；2.对象造型（用父类引用子类型对象，这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为）</li>
<li>抽象：抽象是将一类对象的共同特性总结出来构造类的过程，包括数据抽象和行为抽象。抽象只关注对象有哪些属性和行为，并不关注行为的细节。</li>
</ul>
<h4 id="2-访问修饰符public、private、protected，default"><a href="#2-访问修饰符public、private、protected，default" class="headerlink" title="2.访问修饰符public、private、protected，default"></a>2.访问修饰符public、private、protected，default</h4><div class="table-container">
<table>
<thead>
<tr>
<th>修改符</th>
<th>当前类</th>
<th>同包</th>
<th>子类</th>
<th>其他包</th>
</tr>
</thead>
<tbody>
<tr>
<td>public</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>protected</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
</tr>
<tr>
<td>default</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
</tr>
<tr>
<td>private</td>
<td>√</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<h4 id="3-clone对象"><a href="#3-clone对象" class="headerlink" title="3.clone对象"></a>3.clone对象</h4><h5 id="3-1为什么要用clone"><a href="#3-1为什么要用clone" class="headerlink" title="3.1为什么要用clone"></a>3.1为什么要用clone</h5><p>我需要对象A中的值，需要和A完全相同的新对象B，并且修改B中的值不会影响到A中的值。</p>
<h5 id="3-2-new一个对象的过程和clone一个对象的过程区别"><a href="#3-2-new一个对象的过程和clone一个对象的过程区别" class="headerlink" title="3.2 new一个对象的过程和clone一个对象的过程区别"></a>3.2 new一个对象的过程和clone一个对象的过程区别</h5><p>new操作符是分配内存。程序执行到new操作符时，首先看new操作符后面的类型，知道类型才能分配多大的内存空间。分配完内存之后，再调用构造函数，填充对象的各个域，叫对象的初始化，构造方法返回后，一个对象创建完毕，可以把他的引用（地址）发布到外部，在外部就可以使用这个引用操纵这个对象</p>
<p>clone在第一步是和new相似，都是分配内存，调用clone方法，分配内存和原对象（即调用clone方法的对象）相同，然后再使用原对象中对应的各个域，填充新对象的域，填充完成之后，clone方法返回，一个新的相同的对象被创建，同样可以把这个新对象的引用发布到外部。</p>
<h5 id="3-3clone对象的使用"><a href="#3-3clone对象的使用" class="headerlink" title="3.3clone对象的使用"></a>3.3clone对象的使用</h5><h5 id="3-3-1-复制对象和复制引用的区别"><a href="#3-3-1-复制对象和复制引用的区别" class="headerlink" title="3.3.1 复制对象和复制引用的区别"></a>3.3.1 复制对象和复制引用的区别</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Person p = <span class="keyword">new</span> Person(<span class="number">23</span>,<span class="string">&quot;zhang&quot;</span>);</span><br><span class="line">Person p1 = p;</span><br></pre></td></tr></table></figure>
<p>p和p1只是引用而已，都指向一个相同的对象Person(23,”zhang”)。这种现象叫做引用复制。</p>
<p><img src="images/image-20200310101110579.png" alt="image-20200310101110579"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Person p = <span class="keyword">new</span> Person(<span class="number">23</span>,<span class="string">&quot;zhang&quot;</span>);</span><br><span class="line">Person p1 = (Person)p.clone();</span><br></pre></td></tr></table></figure>
<p>创建了新的对象，叫做对象复制。</p>
<p><img src="images/image-20200310101300559.png" alt="image-20200310101300559"></p>
<h5 id="3-3-2深拷贝和浅拷贝"><a href="#3-3-2深拷贝和浅拷贝" class="headerlink" title="3.3.2深拷贝和浅拷贝"></a>3.3.2深拷贝和浅拷贝</h5><p><img src="images/image-20200310101942828.png" alt="image-20200310101942828"></p>
<p>如何进行深拷贝？</p>
<p>想要深拷贝一个对象，这个对象必须要实现Cloneable接口，实现clone方法，并且在clone方法内部，把该对象引用的其他对象也要clone一份，这就要交这个被引用的对象必须也要实现Cloneable接口并且实现clone方法。</p>
<h3 id="二、JavaSE语法"><a href="#二、JavaSE语法" class="headerlink" title="二、JavaSE语法"></a>二、JavaSE语法</h3><h4 id="1-amp-和-amp-amp-的区别"><a href="#1-amp-和-amp-amp-的区别" class="headerlink" title="1.&amp;和&amp;&amp;的区别"></a>1.&amp;和&amp;&amp;的区别</h4><p>&amp;运算符有两种用法：（1）按位与；（2）逻辑与</p>
<p>&amp;&amp;运算符是短路与运算，&amp;&amp;左边的表达式的值是false，右边的表达式直接短路掉，不会进行运算。</p>
<h4 id="2-两个对象值相同（x-equals-y-true），但却可有不同的hashCode，对不对"><a href="#2-两个对象值相同（x-equals-y-true），但却可有不同的hashCode，对不对" class="headerlink" title="2.两个对象值相同（x.equals(y) == true），但却可有不同的hashCode，对不对"></a>2.两个对象值相同（x.equals(y) == true），但却可有不同的hashCode，对不对</h4><p>不对，如果两个对象x和y满足x.equals(y) == true，它们的哈希码（hashCode）应当相同。</p>
<h4 id="3-是否可以继承String"><a href="#3-是否可以继承String" class="headerlink" title="3.是否可以继承String"></a>3.是否可以继承String</h4><p>string类是final类，不可以被继承</p>
<h4 id="4-当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并返回变化后的结果，那么这里到底是值传递还是引用传递"><a href="#4-当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并返回变化后的结果，那么这里到底是值传递还是引用传递" class="headerlink" title="4.当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并返回变化后的结果，那么这里到底是值传递还是引用传递"></a>4.当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并返回变化后的结果，那么这里到底是值传递还是引用传递</h4><h4 id="5-重载（overload）和重写（override）的区别？重载的方法是否根据返回类型进行区分？"><a href="#5-重载（overload）和重写（override）的区别？重载的方法是否根据返回类型进行区分？" class="headerlink" title="5.重载（overload）和重写（override）的区别？重载的方法是否根据返回类型进行区分？"></a>5.重载（overload）和重写（override）的区别？重载的方法是否根据返回类型进行区分？</h4><p>方法的重载和重写都是实现多态的方法。区别在于前者实现的是编译时多态性，后者实现的是运行时的多态性。重载发生在一个类中，同名的方法如果有不同的参数列表（参数类型不同，参数个数不同或者二者都不同）则视为重载；重写发生在子类和父类之间，重写要求子类被重写方法与父类被重写方法有相同的返回类型，比父类被重写方法更好访问，不能比父类被重写方法声明更多的异常。重载对返回类型没有特殊的要求。</p>
<p>方法重载的规则：</p>
<pre><code>- 方法名一致，参数列表中参数的顺序，类型，个数不同
- 重载与方法的返回值无关，存在于父类和子类，同类中。
- 可以抛出不同的异常，可以有不同的修饰符
</code></pre><p>方法重写的规则：</p>
<pre><code>- 参数列表必须完全被重写方法的一致，返回类型必须完全与被重写方法的返回类型一致
- 构造方法不能被重写，声明为final的方法不能被重写，声明为static的方法不能被重写，但是能够被再次声明
- 访问权限不能被父类中被重写的方法的访问权限更低
- 重写的方法能够抛出非强制异常（UncheckedException，也叫非运行时异常），无论被重写的方法是否抛出异常。但是，重写的方法不能抛出新的强制性异常，或者比被重写方法声明的更广泛的强制性异常，反之则可以。
</code></pre><h4 id="6-为什么函数不能根据返回类型来区分重载"><a href="#6-为什么函数不能根据返回类型来区分重载" class="headerlink" title="6.为什么函数不能根据返回类型来区分重载?"></a>6.为什么函数不能根据返回类型来区分重载?</h4><p>因为调用时不能指定类型信息，编译器不知道你要调用哪个函数。函数的返回值只是作为函数运行之后的一个“状态”，他是保持方法调用者与被调用者进行通信的关键，并不能作为某个方法的“标识”。</p>
<h4 id="7-抽象类（abstract-class）和接口（interface）有什么异同"><a href="#7-抽象类（abstract-class）和接口（interface）有什么异同" class="headerlink" title="7.抽象类（abstract class）和接口（interface）有什么异同"></a>7.抽象类（abstract class）和接口（interface）有什么异同</h4><p>不同：</p>
<p>​    抽象类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">- 抽象类可以定义构造器</span><br><span class="line">- 可以有抽象方法和具体方法</span><br><span class="line">- 抽象类中的成员全都是<span class="keyword">public</span>的</span><br><span class="line">- 抽象类中可以定义成员变量</span><br><span class="line">- 有抽象方法的类必须被申明为抽象类，而抽象类未必要有抽象方法</span><br><span class="line">- 抽象类中可以包含静态方法</span><br><span class="line">- 一个类只能继承一个抽象类</span><br></pre></td></tr></table></figure>
<p>​    接口</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">- </span>接口中不能定义构造器</span><br><span class="line"><span class="bullet">- </span>方法全部都是抽象方法</span><br><span class="line"><span class="bullet">- </span>抽象类的中的成员可以是private default protected public</span><br><span class="line"><span class="bullet">- </span>接口中定义的成员变量实际上都是常量</span><br><span class="line"><span class="bullet">- </span>接口中不能有静态方法</span><br><span class="line"><span class="bullet">- </span>一个类可以实现多个接口</span><br></pre></td></tr></table></figure>
<p>相同：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">- </span>不能够实例化</span><br><span class="line"><span class="bullet">- </span>可以将抽象类和接口类型作为引用类型</span><br><span class="line"><span class="bullet">- </span>一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现，否则该类仍然需要被声明为抽象类</span><br></pre></td></tr></table></figure>
<div class="table-container">
<table>
<thead>
<tr>
<th></th>
<th>抽象类</th>
<th>接口</th>
</tr>
</thead>
<tbody>
<tr>
<td>是否有构造器</td>
<td>有构造器</td>
<td>没有构造器</td>
</tr>
<tr>
<td>成员属性修饰符</td>
<td>只能是public</td>
<td>public protected default private都是常量</td>
</tr>
<tr>
<td>成员方法</td>
<td>抽象方法、具体方法</td>
<td>抽象方法</td>
</tr>
<tr>
<td>是否可以包含静态方法</td>
<td>可以</td>
<td>不可以</td>
</tr>
<tr>
<td></td>
<td>一个类只能继承一个抽象类</td>
<td>一个类可以实现多个接口</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<h4 id="8-抽象的（abstract）方法是否可以同时是静态（static），是否可以同时是本地方法（native），是否同时被synchronized"><a href="#8-抽象的（abstract）方法是否可以同时是静态（static），是否可以同时是本地方法（native），是否同时被synchronized" class="headerlink" title="8. 抽象的（abstract）方法是否可以同时是静态（static），是否可以同时是本地方法（native），是否同时被synchronized"></a>8. 抽象的（abstract）方法是否可以同时是静态（static），是否可以同时是本地方法（native），是否同时被synchronized</h4><p>都不能。抽象方法需要子类重写，而静态方法是无法被重写的，因此二者是矛盾的。本地方法是由本地代码实现的方法，而抽象方法是没有实现的，也是矛盾的。synchronized和方法的实现细节有关，抽象方法不涉及实现细节，因此也是相互矛盾的。</p>
<h4 id="9-阐述静态变量和实例变量的区别"><a href="#9-阐述静态变量和实例变量的区别" class="headerlink" title="9.阐述静态变量和实例变量的区别"></a>9.阐述静态变量和实例变量的区别</h4><p>静态变量：是被static修饰符修饰的变量，也称为类变量，它属于类，不属于类的任何一个对象，一个类不管创建多少个对象，静态变量在内存中有且仅有一个拷贝。</p>
<p>实例变量：必须依存于某一个实例，需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。</p>
<h4 id="10-和equals的区别"><a href="#10-和equals的区别" class="headerlink" title="10. ==和equals的区别"></a>10. ==和equals的区别</h4><p>equals和== 最大的区别是一个方法一个是运算符。</p>
<p>==：如果比较的对象是基本数据类型，则比较的是数值是否相等；如果比较的是引用数据类型，则比较的是对象的地址指是否相等。</p>
<p>equals()：用来比较方法两个对象的内容是否相等。不能用于基本数据类型的变量，如果没有对equals方法进行重写，则比较的是引用类型的变量所指向的对象的地址。</p>
<h4 id="11-break和continue的区别？"><a href="#11-break和continue的区别？" class="headerlink" title="11. break和continue的区别？"></a>11. break和continue的区别？</h4><p>break和continue都是用来控制循环的语句。</p>
<p>break用于完全结束一个循环，跳出循环体执行循环后面的语句</p>
<p>continue用于跳出本次循环，执行下次循环</p>
<h4 id="12-String-s-“Hello”-s-s-“world-”-这两行代码执行后，原始的String对象中的内容到底变了没有？"><a href="#12-String-s-“Hello”-s-s-“world-”-这两行代码执行后，原始的String对象中的内容到底变了没有？" class="headerlink" title="12.String s = “Hello”; s =s + “world!”; 这两行代码执行后，原始的String对象中的内容到底变了没有？"></a>12.String s = “Hello”; s =s + “world!”; 这两行代码执行后，原始的String对象中的内容到底变了没有？</h4><p>没有变。因为String被设计成不可变类，所以它的所有对象都是不可变对象。s不指向原来那个对象了，而是指向了另一个String对象,内容是”Hello World！”，原来那个对象还存在内存之中，只是s这个引用变量不再指向它了。</p>
<h3 id="三、Java中的多态"><a href="#三、Java中的多态" class="headerlink" title="三、Java中的多态"></a>三、Java中的多态</h3><h4 id="1-Java中实现多态的机制是什么？"><a href="#1-Java中实现多态的机制是什么？" class="headerlink" title="1. Java中实现多态的机制是什么？"></a>1. Java中实现多态的机制是什么？</h4><p>是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象，而程序调用的方法在运行期才动态绑定，就是引用变量所指向的具体实例对象的方法，也就是内存里正在运行的那个对象的方法，而不是引用变量的类型中定义的方法。</p>
<h3 id="四、Java的异常处理"><a href="#四、Java的异常处理" class="headerlink" title="四、Java的异常处理"></a>四、Java的异常处理</h3><h4 id="1-Java中异常分为哪些种类"><a href="#1-Java中异常分为哪些种类" class="headerlink" title="1.Java中异常分为哪些种类"></a>1.Java中异常分为哪些种类</h4><p>按照异常需要处理的时机分为编译时异常（强制性异常）也叫CheckedException和运行时异常（非强制性异常）也叫RuntimeException。Checked异常都是可以被处理的异常，Java程序必须显式处理Checked异常，如果程序没有处理Checked异常，该程序在编译时就会发生错误无法编译。</p>
<p>对Checked异常处理方法有两种：</p>
<ol>
<li>当前方法知道如何处理该异常，则用try…catch块来处理该异常。</li>
<li>当前方法不知道如何处理，则在定义该方法是声明抛出异常。</li>
</ol>
<p>运行时异常只有当代码在运行时才发行的异常，编译时不需要try…catch。Runtime如除数是0和数组下标越界等。</p>
<h4 id="2-调用下面的方法，得到的返回值是什么？"><a href="#2-调用下面的方法，得到的返回值是什么？" class="headerlink" title="2.调用下面的方法，得到的返回值是什么？"></a>2.调用下面的方法，得到的返回值是什么？</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getNum</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">1</span> / <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;<span class="keyword">catch</span> (Exception e)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">    &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">3</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>代码走到<code>int a = 1 / 0</code>时候遇到MathException，<code>return 1;</code>不会执行，代码直接跳到catch语句中，异常机制有一个原则在catch中遇到return或者异常等能使该函数终止的话，那么有finally就必须先执行完finally代码块里面的代码，代码又跳到<code>return 3</code>，它是return语句，这时方法结结束了。如果不是return语句，那么返回的是2，因此上面返回值是3.</p>
<h4 id="3-error和exception的区别？"><a href="#3-error和exception的区别？" class="headerlink" title="3. error和exception的区别？"></a>3. error和exception的区别？</h4><p>Error类和Exception类的父类都是Throwable类，区别如下：</p>
<h3 id="五、JavaSE常用API"><a href="#五、JavaSE常用API" class="headerlink" title="五、JavaSE常用API"></a>五、JavaSE常用API</h3><h3 id="六、Java的数据类型"><a href="#六、Java的数据类型" class="headerlink" title="六、Java的数据类型"></a>六、Java的数据类型</h3><h4 id="1-Java的基本数据类型都有哪些各占几个字节"><a href="#1-Java的基本数据类型都有哪些各占几个字节" class="headerlink" title="1.Java的基本数据类型都有哪些各占几个字节"></a>1.Java的基本数据类型都有哪些各占几个字节</h4><p>Java的基本数据类型四类八种</p>
<h4 id="2-String是基本数据类型吗"><a href="#2-String是基本数据类型吗" class="headerlink" title="2.String是基本数据类型吗?"></a>2.String是基本数据类型吗?</h4><p>String是引用类型，底层用char数组实现的</p>
<h4 id="3-short-s1-1-s1-s1-1-有错吗？short-s1-1-s1-1有错吗？"><a href="#3-short-s1-1-s1-s1-1-有错吗？short-s1-1-s1-1有错吗？" class="headerlink" title="3. short s1 = 1; s1 = s1 + 1;有错吗？short s1 = 1; s1 += 1有错吗？"></a>3. short s1 = 1; s1 = s1 + 1;有错吗？short s1 = 1; s1 += 1有错吗？</h4><p>前者不正确，后者正确。对于short s1 = 1; s1 = s1 + 1; 由于1是int类型，因此s1 + 1运算结果也是int型，需要强制转换类型才能赋值给short类型。而short s1 = 1; s1 += 1; 可以正确编译，因为s1 += 1;相当于s1 = (short)(s1 + 1),其中有隐含的强制类型装换。</p>
<h4 id="4-int和Integer有什么区别？"><a href="#4-int和Integer有什么区别？" class="headerlink" title="4. int和Integer有什么区别？"></a>4. int和Integer有什么区别？</h4><p>为了能够将基本数据类型当成对象操作，Java为每一个基本数据类型都引入了对应的包装类型。</p>
<p>原始类型：boolean，char，byte，short，int，long，double，float</p>
<p>包装类型：Boolean，Character，Byte，Short，Integer，Long，Double，Float</p>
<h4 id="5-下面Integer类型的数值比较输出的结果为？"><a href="#5-下面Integer类型的数值比较输出的结果为？" class="headerlink" title="5.下面Integer类型的数值比较输出的结果为？"></a>5.下面Integer类型的数值比较输出的结果为？</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Integer f1 = <span class="number">100</span>, f2 = <span class="number">100</span>, f3 = <span class="number">150</span>, f4 = <span class="number">150</span>;</span><br><span class="line">System.out.println(f1 == f2);</span><br><span class="line">System.out.println(f3 == f4);</span><br></pre></td></tr></table></figure>
<p>首先注意的是f1，f2，f3，f4四个变量都是Integer对象引用，所以下面的==运算比较的不是值而是引用。装箱的本质的是什么？当我们给一个Integer对象赋值一个int值的时候，会调用Integer类的静态方法valueOf。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Integer <span class="title">valueOf</span><span class="params">(<span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (i &gt;= IntegerCache.low &amp;&amp; i &lt;= IntegerCache.high)</span><br><span class="line">        <span class="keyword">return</span> IntegerCache.cache[i + (-IntegerCache.low)];</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Integer(i);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>IntegerCache是Integer的内部类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">IntegerCache</span> </span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> low = -<span class="number">128</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> high;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> Integer cache[];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="comment">// high value may be configured by property</span></span><br><span class="line">        <span class="keyword">int</span> h = <span class="number">127</span>;</span><br><span class="line">        String integerCacheHighPropValue =</span><br><span class="line">            VM.getSavedProperty(<span class="string">&quot;java.lang.Integer.IntegerCache.high&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (integerCacheHighPropValue != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">int</span> i = parseInt(integerCacheHighPropValue);</span><br><span class="line">                i = Math.max(i, <span class="number">127</span>);</span><br><span class="line">                <span class="comment">// Maximum array size is Integer.MAX_VALUE</span></span><br><span class="line">                h = Math.min(i, Integer.MAX_VALUE - (-low) -<span class="number">1</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span>( NumberFormatException nfe) &#123;</span><br><span class="line">                <span class="comment">// If the property cannot be parsed into an int, ignore it.</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        high = h;</span><br><span class="line"></span><br><span class="line">        cache = <span class="keyword">new</span> Integer[(high - low) + <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">int</span> j = low;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> k = <span class="number">0</span>; k &lt; cache.length; k++)</span><br><span class="line">            cache[k] = <span class="keyword">new</span> Integer(j++);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// range [-128, 127] must be interned (JLS7 5.1.7)</span></span><br><span class="line">        <span class="keyword">assert</span> IntegerCache.high &gt;= <span class="number">127</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">IntegerCache</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>如果整型字面量的值在-128到127之间，那么不会new新的Integer对象，而是直接引用常量池中的Integer对象，所以f1 == f2的结果是true，f3 == f4的结果是false。</p>
<h4 id="6-String、StringBuffer、Stringuilder的区别"><a href="#6-String、StringBuffer、Stringuilder的区别" class="headerlink" title="6.String、StringBuffer、Stringuilder的区别"></a>6.String、StringBuffer、Stringuilder的区别</h4><h5 id="6-1-可变性"><a href="#6-1-可变性" class="headerlink" title="6.1 可变性"></a>6.1 可变性</h5><p>String：字符串常量，String类中使用final关键字修饰字符数组来保存字符串，private final char value[],所以String对象是不可变的，在修改时不会改变自身；若修改，等于重新生成新的字符串对象</p>
<p>StringBuilder与StringBuffer：StringBuilder与StringBuffer都继承自AbstractStringBuilder类，在AbstractStringBuilder中也是使用字符数组保存字符串char[] value 但是没有用final关键字修饰，所以在修改时会改变对象自身，每次操作都是对StringBuffer对象本身进行修改，不是生成新的对象；使用场景：字符串经常改变情况下。</p>
<h5 id="6-2-线程是够安全"><a href="#6-2-线程是够安全" class="headerlink" title="6.2 线程是够安全"></a>6.2 线程是够安全</h5><p>String：对象定义后不可改变，线程安全；</p>
<p>StringBuffer：是线程安全的（对调用方法加入同步锁），执行效率较慢，适合用于多线程下操作字符串缓冲区大量数据。</p>
<p>StringBuilder：是线程不安全的，适用于单线程下操作字符串缓冲区大量数据</p>
<h5 id="6-3-共同点"><a href="#6-3-共同点" class="headerlink" title="6.3 共同点"></a>6.3 共同点</h5><p>StringBuilder和StringBuffer有公共父类AbstractStringBuilder(抽象类)。</p>
<p>StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法，只是StringBuffer会在方法上加synchronized关键字，进行同步。</p>
<h5 id="6-4-总结"><a href="#6-4-总结" class="headerlink" title="6.4 总结"></a>6.4 总结</h5><ul>
<li>操作少量的数据：适用String</li>
<li>单线程操作字符串缓冲区下操作大量数据：适用于StringBuilder</li>
<li>多线程操作字符串缓冲区下操作大量数据：适用于StringBuffer</li>
</ul>
<h4 id="7-数据类型之间的转换"><a href="#7-数据类型之间的转换" class="headerlink" title="7. 数据类型之间的转换"></a>7. 数据类型之间的转换</h4><h5 id="7-1-字符串如何转基本数据类型？"><a href="#7-1-字符串如何转基本数据类型？" class="headerlink" title="7.1 字符串如何转基本数据类型？"></a>7.1 字符串如何转基本数据类型？</h5><p>调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型。</p>
<h5 id="7-2-基本数据类型如何转字符串"><a href="#7-2-基本数据类型如何转字符串" class="headerlink" title="7.2 基本数据类型如何转字符串"></a>7.2 基本数据类型如何转字符串</h5><p>一种方法是将基本数据类型与空字符串(“”)连接(+)即可获得其所对应的字符串；另一个方法是调用String类中的valueOf()方法返回相应字符串。</p>
<h3 id="七、Java的IO"><a href="#七、Java的IO" class="headerlink" title="七、Java的IO"></a>七、Java的IO</h3><h3 id="八、Java的集合"><a href="#八、Java的集合" class="headerlink" title="八、Java的集合"></a>八、Java的集合</h3><h4 id="1-说啥常见的集合有哪些？"><a href="#1-说啥常见的集合有哪些？" class="headerlink" title="1.说啥常见的集合有哪些？"></a>1.说啥常见的集合有哪些？</h4><p>Collection接口和Map接口是所有集合框架的父接口。</p>
<ul>
<li>Collection接口的子接口包含Set接口和List接口<ul>
<li>Set接口<ul>
<li>HashSet、LinkedHashSet、TreeSet</li>
</ul>
</li>
<li>List接口<ul>
<li>ArrayList、LinkedList、Stack、Vector</li>
</ul>
</li>
</ul>
</li>
<li>Map接口主要的实现类<ul>
<li>HashMap、TreeMap、HashTable</li>
</ul>
</li>
</ul>
<h4 id="2-HashMap和HashTable的区别"><a href="#2-HashMap和HashTable的区别" class="headerlink" title="2.HashMap和HashTable的区别"></a>2.HashMap和HashTable的区别</h4><div class="table-container">
<table>
<thead>
<tr>
<th></th>
<th>线程安全</th>
<th>继承类</th>
<th>是否允许为null值作为key值或value值</th>
</tr>
</thead>
<tbody>
<tr>
<td>HashMap</td>
<td>非线程安全</td>
<td>AbstrackMap类</td>
<td>是</td>
</tr>
<tr>
<td>HashTable</td>
<td>线程安全</td>
<td>Dictionary</td>
<td>否</td>
</tr>
</tbody>
</table>
</div>
<h4 id="3-HashMap的put方法的具体流程"><a href="#3-HashMap的put方法的具体流程" class="headerlink" title="3.HashMap的put方法的具体流程"></a>3.HashMap的put方法的具体流程</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> V <span class="title">put</span><span class="params">(K key, V value)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> putVal(hash(key), key, value, <span class="keyword">false</span>, <span class="keyword">true</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>首先调用hash函数，重新计算key的hash值</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> <span class="title">hash</span><span class="params">(Object key)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> h;</span><br><span class="line">    <span class="keyword">return</span> (key == <span class="keyword">null</span>) ? <span class="number">0</span> : (h = key.hashCode()) ^ (h &gt;&gt;&gt; <span class="number">16</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过h = key.hashCode()方法计算key的hashcode值，通过计算出的hashcode的值向右移动16位，使原有的hashcode的高位变低位，高16位则统一都变为0.</p>
<p>异或运算<code>(h = key.hashcode()) ^ (h &gt;&gt;&gt; 16)</code> 可以将hashcode高位和地位的值进行混合做异或运算，而且混合后，低位的信息中加入了高位的信息，这样高位的信息被变相的保留下来。</p>
<h4 id="4-HashMap的扩容操作是怎么实现的"><a href="#4-HashMap的扩容操作是怎么实现的" class="headerlink" title="4. HashMap的扩容操作是怎么实现的"></a>4. HashMap的扩容操作是怎么实现的</h4><p>通过分析源码我们知道了HashMap通过<code>resize()</code>方法进行扩容或者初始化操作。</p>
<h4 id="5-HashMap在JDK1-7和JDK1-8中有哪些不同"><a href="#5-HashMap在JDK1-7和JDK1-8中有哪些不同" class="headerlink" title="5. HashMap在JDK1.7和JDK1.8中有哪些不同"></a>5. HashMap在JDK1.7和JDK1.8中有哪些不同</h4><h4 id="6-ArrayList和Vector的区别"><a href="#6-ArrayList和Vector的区别" class="headerlink" title="6.ArrayList和Vector的区别"></a>6.ArrayList和Vector的区别</h4><h4 id="7-Array和ArrayList有什么区别？什么时候用Array而不是ArrayLsit呢？"><a href="#7-Array和ArrayList有什么区别？什么时候用Array而不是ArrayLsit呢？" class="headerlink" title="7. Array和ArrayList有什么区别？什么时候用Array而不是ArrayLsit呢？"></a>7. Array和ArrayList有什么区别？什么时候用Array而不是ArrayLsit呢？</h4><h4 id="8-Set里的元素是不能重复的，那么用什么方法来区分重复与否呢？是用-还是equals"><a href="#8-Set里的元素是不能重复的，那么用什么方法来区分重复与否呢？是用-还是equals" class="headerlink" title="8.Set里的元素是不能重复的，那么用什么方法来区分重复与否呢？是用==还是equals()?"></a>8.Set里的元素是不能重复的，那么用什么方法来区分重复与否呢？是用==还是equals()?</h4><h4 id="9-ArrayList与LinkedList异同？"><a href="#9-ArrayList与LinkedList异同？" class="headerlink" title="9.ArrayList与LinkedList异同？"></a>9.ArrayList与LinkedList异同？</h4><p>ArrayList和Vector使用了数组的实现，可以认为ArrayList或者Vector封装了对内部数组的操作，比如向数组中添加，删除，插入新的元素或者书籍的扩展和重定向。</p>
<p>LinkedList使用了循环双向链表数据结构。LinkedList链表由一系列表项连接而成。一个表项总是包含3个部分：元素内容，前驱表和驱表。</p>
<p><img src="images/image-20200313084953447.png" alt="image-20200313084953447"></p>
<p>无论LinkedList是否为空，链表内部都有一个header表项，它既表示链表的开始，也表示链表的结尾。表项header的后驱表项便是链表中第一个元素，表项header的前驱表项便是链表中最后一个元素。</p>
<p><img src="images/image-20200313090416725.png" alt="image-20200313090416725"></p>
<h4 id="10-要对集合更新操作时，ArrayList和LinkedList哪个更合适？"><a href="#10-要对集合更新操作时，ArrayList和LinkedList哪个更合适？" class="headerlink" title="10.要对集合更新操作时，ArrayList和LinkedList哪个更合适？"></a>10.要对集合更新操作时，ArrayList和LinkedList哪个更合适？</h4><h4 id="11-List和Map区别"><a href="#11-List和Map区别" class="headerlink" title="11. List和Map区别"></a>11. List和Map区别</h4><h4 id="12-Collection和Collections的区别？"><a href="#12-Collection和Collections的区别？" class="headerlink" title="12. Collection和Collections的区别？"></a>12. Collection和Collections的区别？</h4><h4 id="13-如何选用集合"><a href="#13-如何选用集合" class="headerlink" title="13.如何选用集合"></a>13.如何选用集合</h4><h4 id="14-说出ArrayList，Vector，LinkedList的存储性能和特性"><a href="#14-说出ArrayList，Vector，LinkedList的存储性能和特性" class="headerlink" title="14. 说出ArrayList，Vector，LinkedList的存储性能和特性"></a>14. 说出ArrayList，Vector，LinkedList的存储性能和特性</h4><h4 id="15-哪些集合类是线程安全的？"><a href="#15-哪些集合类是线程安全的？" class="headerlink" title="15.哪些集合类是线程安全的？"></a>15.哪些集合类是线程安全的？</h4><h4 id="16-HashMap排序题"><a href="#16-HashMap排序题" class="headerlink" title="16.HashMap排序题"></a>16.HashMap排序题</h4><p>已知一个HashMap<Integer,User>集合，User有name（String）和age（int）属性。请写一个方法实现对HashMap的排序功能。该方法接收HashMap<Integet,User>为形参，返回类型为HashMap<Integer,User>,要求对HashMap中的User的age倒序进行排序，排序时key=value键值对不得拆散。</p>
<p>注意：HashMap本身就是不可排序，在API中有没有Map结构是有序的，LinkedHashMap，它是Map结构，也是链表结构，有序的，还是HashMap的子类。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    HashMap&lt;Integer,User&gt; users = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">    users.put(<span class="number">1</span>,<span class="keyword">new</span> User(<span class="string">&quot;张三&quot;</span>,<span class="number">12</span>));</span><br><span class="line">    users.put(<span class="number">3</span>,<span class="keyword">new</span> User(<span class="string">&quot;李四&quot;</span>,<span class="number">52</span>));</span><br><span class="line">    users.put(<span class="number">2</span>,<span class="keyword">new</span> User(<span class="string">&quot;王五&quot;</span>,<span class="number">42</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;——————排序前——————————&quot;</span>);</span><br><span class="line">    System.out.println(users);</span><br><span class="line">    System.out.println(<span class="string">&quot;——————排序后——————————&quot;</span>);</span><br><span class="line">    System.out.println(sortHashMap(users));</span><br><span class="line">	 <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * ——————排序前——————————</span></span><br><span class="line"><span class="comment">         * &#123;1=User&#123;name=&#x27;张三&#x27;, age=12&#125;, 2=User&#123;name=&#x27;王五&#x27;, age=42&#125;, 3=User&#123;name=&#x27;李四&#x27;, age=52&#125;&#125;</span></span><br><span class="line"><span class="comment">         * ——————排序后——————————</span></span><br><span class="line"><span class="comment">         * &#123;3=User&#123;name=&#x27;李四&#x27;, age=52&#125;, 2=User&#123;name=&#x27;王五&#x27;, age=42&#125;, 1=User&#123;name=&#x27;张三&#x27;, age=12&#125;&#125;</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> HashMap&lt;Integer,User&gt; <span class="title">sortHashMap</span><span class="params">(HashMap&lt;Integer,User&gt; map)</span></span>&#123;</span><br><span class="line">    <span class="comment">//先拿到map的键值对集合</span></span><br><span class="line">    Set&lt;Map.Entry&lt;Integer,User&gt;&gt; entrySet = map.entrySet();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将set集合转为List集合，为了适用工具类的排序方法</span></span><br><span class="line">    List&lt;Map.Entry&lt;Integer,User&gt;&gt; list = <span class="keyword">new</span> ArrayList&lt;Map.Entry&lt;Integer,User&gt;&gt;(entrySet);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//适用Collections集合工具类对List进行排序</span></span><br><span class="line">     Collections.sort(list, ((o1, o2) -&gt; &#123;<span class="keyword">return</span> o2.getValue().getAge() - o1.getValue().getAge();&#125;));</span><br><span class="line"></span><br><span class="line">    <span class="comment">//创建一个新的有序的HashMap子类的集合</span></span><br><span class="line">    LinkedHashMap&lt;Integer,User&gt; integerUserLinkedHashMap = <span class="keyword">new</span> LinkedHashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将List的数据存储在LinkedHashMap中</span></span><br><span class="line">    <span class="keyword">for</span> (Map.Entry&lt;Integer, User&gt; integerUserEntry : list) &#123;</span><br><span class="line">        integerUserLinkedHashMap.put(integerUserEntry.getKey(),integerUserEntry.getValue());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> integerUserLinkedHashMap;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> Integer age;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">User</span><span class="params">(String name, Integer age)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Integer <span class="title">getAge</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(Integer age)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;User&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;name=&#x27;&quot;</span> + name + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, age=&quot;</span> + age +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


        <hr>
        <!-- Pager -->
        <ul class="pager">
          
          <li class="previous">
            <a href="/cn/javaScript/js判断是否为空对象/" data-toggle="tooltip" data-placement="top" title="js判断是否为空对象">&larr; Previous Post</a>
          </li>
          
          
          <li class="next">
            <a href="/cn/spring/SSM整合Swagger/" data-toggle="tooltip" data-placement="top" title="SSM整合Swagger">Next Post &rarr;</a>
          </li>
          
        </ul>

        
        <!-- tip start -->
        <!-- tip -->
<!-- tip start -->
<div class="tip">
  <p>
    
      如果您喜欢此博客或发现它对您有用，则欢迎对此发表评论。 也欢迎您共享此博客，以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权，请与作者联系以将其删除。 谢谢 ！
    
  </p>
</div>
<!-- tip end -->

        <!-- tip end -->
        

        
        <hr>

        <!-- comments start -->
        <!-- 1. gitalk comment -->


<!-- 2. gitment comment -->


<!-- 3. disqus comment -->


        <!-- comments end -->
        <hr>

      </div>

      <!-- Catalog: Tabe of Content -->
      <!-- Table of Contents -->



      <!-- Sidebar Container -->
      <div class="
                col-lg-8 col-lg-offset-1
                col-md-10 col-md-offset-1
                sidebar-container">

        <!-- Featured Tags -->
        
        <section>
          <!-- no hr -->
          <h5>
            <a href="/tags/">特色标签</a>
          </h5>
          <div class="tags">
            
            <a class="tag" href="/tags/#java" title="java">java</a>
            
            <a class="tag" href="/tags/#面试" title="面试">面试</a>
            
          </div>
        </section>
        

        <!-- Friends Blog -->
        
        <hr>
        <h5>链友</h5>
        <ul class="list-inline">

          
        </ul>
        
      </div>
    </div>
  </div>
</article>



<!-- anchorjs start -->
<!-- async load function -->
<!-- anchor-js, Doc:http://bryanbraun.github.io/anchorjs/ -->
<script type="text/javascript">
  // async load function
  function async (u, c) {
    var d = document,
      t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) {
      o.addEventListener('load', function(e) {
        c(null, e);
      }, false);
    }
    s.parentNode.insertBefore(o, s);
  };
</script>
<script type="text/javascript">
  //anchor-js, Doc:http://bryanbraun.github.io/anchorjs/
  async ("https://cdn.bootcss.com/anchor-js/1.1.1/anchor.min.js", function() {
    anchors.options = {
      visible: 'hover',
      placement: 'left',
      // icon: 'ℬ'
      icon: '❡'
    };
    anchors.add().remove('.intro-header h1').remove('.subheading').remove('.sidebar-container h5');
  });
</script>
<style>
  /* place left on bigger screen */
  @media all and (min-width: 800px) {
    .anchorjs-link {
      position: absolute;
      left: -0.75em;
      font-size: 1.1em;
      margin-top: -0.1em;
    }
  }
</style>

<!-- anchorjs end -->



		<!-- Footer (contains ThemeColor、viewer) -->
		<!-- Footer -->
<footer>
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <ul class="list-inline text-center">
          

          

          

          

          

          

          

          

        </ul>
        <p class="copyright text-muted">
          Copyright &copy;
          zhuang
          2021
          <br>
          Theme by
          <a target="_blank" rel="noopener" href="http://beantech.org">BeanTech</a>
          <span style="display: inline-block; margin: 0 5px;">
            <i class="fa fa-heart"></i>
          </span>
          re-Ported by
          <a target="_blank" rel="noopener" href="https://v-vincen.life/">Live My Life</a>
        </p>
      </div>
    </div>
  </div>
</footer>

<a id="rocket" href="#top" class=""></a>


  <!-- jQuery -->
  <script type="text/javascript" src="/js/jquery.min.js"></script>
  <!-- Bootstrap Core JavaScript -->
  <script type="text/javascript" src="/js/bootstrap.min.js"></script>
  <!-- Custom Theme JavaScript -->
  <script type="text/javascript" src="/js/hux-blog.min.js"></script>
  <!-- catalog -->
  <script async="true" type="text/javascript" src="/js/catalog.js"></script>
  <!-- totop(rocket) -->
  <script async="true" type="text/javascript" src="/js/totop.js"></script>

  
    <!-- Busuanzi JavaScript -->
    <script async="async" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  

  
    <!-- Scroll start -->
    <script async="async" type="text/javascript" src="/js/scroll.js"></script>
    <!-- Scroll end -->
  

  

  

  
    <!-- ribbon -->
    <script type="text/javascript" src="/js/ribbonDynamic.js"></script>
  

  






  <!-- viewer start -->
  <!-- viewer start (Picture preview) -->
  
    <script async="async" type="text/javascript" src="/js/viewer/viewer.min.js"></script>
    <script async="async" type="text/javascript" src="/js/viewer/pic-viewer.js"></script>
  

  <!-- viewer end -->


<script>
  // async load function
  function async (u, c) {
    var d = document,
      t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) {
      o.addEventListener('load', function (e) {
        c(null, e);
      }, false);
    }
    s.parentNode.insertBefore(o, s);
  }

  // fastClick.js
  async ("https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function () {
    var $nav = document.querySelector("nav");
    if ($nav)
      FastClick.attach($nav);
    }
  )
</script>

<!-- Because of the native support for backtick-style fenced code blocks right within the Markdown is landed in Github Pages, From V1.6, There is no need for Highlight.js, so Huxblog drops it officially. -
https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 - https://help.github.com/articles/creating-and-highlighting-code-blocks/ -->
<!-- <script> async ("http://cdn.bootcss.com/highlight.js/8.6/highlight.min.js", function () { hljs.initHighlightingOnLoad(); }) </script> <link href="http://cdn.bootcss.com/highlight.js/8.6/styles/github.min.css" rel="stylesheet"> -->

<!-- jquery.tagcloud.js -->
<!-- <script> // only load tagcloud.js in tag.html if ($('#tag_cloud').length !== 0) { async ("http://yoursite-url/js/jquery.tagcloud.js", function () { $.fn.tagcloud.defaults = { // size: { start: 1, end: 1, unit: 'em' }, color: {
start: '#bbbbee', end: '#0085a1' } }; $('#tag_cloud a').tagcloud(); }) } </script> -->


		<!-- Search -->
		
		<div class="popup search-popup local-search-popup">
  <span class="popup-btn-close">
    ESC
  </span>
  <div class="container">
    <div class="row">
      <!-- <div class="col-md-9 col-md-offset-1"> -->
      <div class="col-lg-9 col-lg-offset-1 col-md-10 col-md-offset-1 local-search-content">

        <div class="local-search-header clearfix">

          <div class="local-search-input-wrapper">
            <span class="search-icon">
              <i class="fa fa-search fa-lg" style="margin: 25px 10px 25px 20px;"></i>
            </span>
            <input autocomplete="off" placeholder="搜索..." type="text" id="local-search-input">
          </div>
        </div>
        <div id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>


  
    <script src="/js/ziploader.js"></script>
  
  <script>
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.json";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    // monitor main search box;
    var onPopupClose = function (e) {
      $('.popup').fadeOut(300);
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $('.popup').fadeIn(300);
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }
    // get search zip version
    $.get('/searchVersion.json?t=' + (+new Date()), function (res) {
      if (localStorage.getItem('searchVersion') !== res) {
        localStorage.setItem('searchVersion', res);
        initSearchJson();
      }
    });

    function initSearchJson() {
      initLoad(['/search.flv'], {
        loadOptions: {
          success: function (obj) {
            localStorage.setItem('searchJson', obj['search.json'])
          },
          error: function (e) {
            return console.log(e)
          }
        },
        returnOptions: {
          'json': TYPE_TEXT
        },
        mimeOptions: {
          'json': 'application/json'
        }
      })
    }
    // search function;
    var searchFunc = function (search_id, content_id) {
      'use strict';
      isfetched = true;
      var datas = JSON.parse(localStorage.getItem('searchJson'));
      // console.log(search_id)
      var input = document.getElementById(search_id);
      var resultContent = document.getElementById(content_id);
      var inputEventFunction = function () {
        var searchText = input.value.trim().toLowerCase();
        var keywords = searchText.split(/[\s\-]+/);
        if (keywords.length > 1) {
          keywords.push(searchText);
        }
        var resultItems = [];
        if (searchText.length > 0) {
          // perform local searching
          datas.forEach(function (data) {
            var isMatch = false;
            var hitCount = 0;
            var searchTextCount = 0;
            var title = data.title
              ? data.title.trim()
              : '';
            var titleInLowerCase = title.toLowerCase();
            var content = data.content
              ? data.content.trim().replace(/<[^>]+>/g, "")
              : '';
            var contentInLowerCase = content.toLowerCase();
            var articleUrl = decodeURIComponent(data.url);

            var date = data.date;
            var dateTime = date.replace(/T/, " ").replace(/.000Z/, "");
            var imgUrl = data.header_img;
            


            var indexOfTitle = [];
            var indexOfContent = [];
            // only match articles with not empty titles
            keywords.forEach(function (keyword) {
              function getIndexByWord(word, text, caseSensitive) {
                var wordLen = word.length;
                if (wordLen === 0) {
                  return [];
                }
                var startPosition = 0,
                  position = [],
                  index = [];
                if (!caseSensitive) {
                  text = text.toLowerCase();
                  word = word.toLowerCase();
                }
                while ((position = text.indexOf(word, startPosition)) > -1) {
                  index.push({position: position, word: word});
                  startPosition = position + wordLen;
                }
                return index;
              }
              indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
              indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
            });
            if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
              isMatch = true;
              hitCount = indexOfTitle.length + indexOfContent.length;
            }
            // show search results
            if (isMatch) {
              // sort index by position of keyword
              [indexOfTitle, indexOfContent].forEach(function (index) {
                index.sort(function (itemLeft, itemRight) {
                  if (itemRight.position !== itemLeft.position) {
                    return itemRight.position - itemLeft.position;
                  } else {
                    return itemLeft.word.length - itemRight.word.length;
                  }
                });
              });
              // merge hits into slices
              function mergeIntoSlice(text, start, end, index) {
                var item = index[index.length - 1];
                var position = item.position;
                var word = item.word;
                var hits = [];
                var searchTextCountInSlice = 0;
                while (position + word.length <= end && index.length != 0) {
                  if (word === searchText) {
                    searchTextCountInSlice++;
                  }
                  hits.push({position: position, length: word.length});
                  var wordEnd = position + word.length;
                  // move to next position of hit
                  index.pop();
                  while (index.length != 0) {
                    item = index[index.length - 1];
                    position = item.position;
                    word = item.word;
                    if (wordEnd > position) {
                      index.pop();
                    } else {
                      break;
                    }
                  }
                }
                searchTextCount += searchTextCountInSlice;
                return {hits: hits, start: start, end: end, searchTextCount: searchTextCountInSlice};
              }
              var slicesOfTitle = [];
              if (indexOfTitle.length != 0) {
                slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
              }
              var slicesOfContent = [];
              while (indexOfContent.length != 0) {
                var item = indexOfContent[indexOfContent.length - 1];
                var position = item.position;
                var word = item.word;
                // cut out 100 characters
                var start = position - 20;
                var end = position + 80;
                if (start < 0) {
                  start = 0;
                }
                if (end < position + word.length) {
                  end = position + word.length;
                }
                if (end > content.length) {
                  end = content.length;
                }
                slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
              }
              // sort slices in content by search text's count and hits' count
              slicesOfContent.sort(function (sliceLeft, sliceRight) {
                if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                  return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                  return sliceRight.hits.length - sliceLeft.hits.length;
                } else {
                  return sliceLeft.start - sliceRight.start;
                }
              });
              // select top N slices in content
              var upperBound = parseInt('1');
              if (upperBound >= 0) {
                slicesOfContent = slicesOfContent.slice(0, upperBound);
              }
              // highlight title and content
              function highlightKeyword(text, slice) {
                var result = '';
                var prevEnd = slice.start;
                slice.hits.forEach(function (hit) {
                  result += text.substring(prevEnd, hit.position);
                  var end = hit.position + hit.length;
                  result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                  prevEnd = end;
                });
                result += text.substring(prevEnd, slice.end);
                return result;
              }
              var resultItem = '';

              // if (slicesOfTitle.length != 0) {   resultItem += "<li><a target='_blank' href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>"; } else {   resultItem += "<li><a target='_blank' href='" +
              // articleUrl + "' class='search-result-title'>" + title + "</a>"; } slicesOfContent.forEach(function (slice) {   resultItem += "<a target='_blank' href='" + articleUrl + "'><p class=\"search-result\">" + highlightKeyword(content, slice) +
              // "...</p></a>"; }); resultItem += "</li>";

              if (slicesOfTitle.length != 0) {
                resultItem += "<a target='_blank' href='" + articleUrl + "' class='search-result'><div class='search-result-left'><div class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</div><time class='search-result-date'>" + dateTime + "</time>";
              } else {
                resultItem += "<a target='_blank' href='" + articleUrl + "' class='search-result'><div class='search-result-left'><div class='search-result-title'>" + title + "</div><time class='search-result-date'>" + dateTime + "</time>";
              }
              slicesOfContent.forEach(function (slice) {
                resultItem += "<p class=\"search-result-content\">" + highlightKeyword(content, slice) + "...</p>";
              });
              resultItem += "</div><div class='search-result-right'><img class='media-image' src='" + imgUrl + "' width='64px' height='48px'></img></div></a>";

              resultItems.push({item: resultItem, searchTextCount: searchTextCount, hitCount: hitCount, id: resultItems.length});
            }
          })
        };

        if (keywords.length === 1 && keywords[0] === "") {
          resultContent.innerHTML = '<div id="no-result"></div>'
        } else if (resultItems.length === 0) {
          resultContent.innerHTML = '<div id="no-result"></div>'
        } else {
          resultItems.sort(function (resultLeft, resultRight) {
            if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
              return resultRight.searchTextCount - resultLeft.searchTextCount;
            } else if (resultLeft.hitCount !== resultRight.hitCount) {
              return resultRight.hitCount - resultLeft.hitCount;
            } else {
              return resultRight.id - resultLeft.id;
            }
          });
          var searchResultList = '<div class=\"search-result-list\">';
          resultItems.forEach(function (result) {
            searchResultList += result.item;
          })
          searchResultList += "</div>";
          resultContent.innerHTML = searchResultList;
        }
      }
      if ('auto' === 'auto') {
        input.addEventListener('input', inputEventFunction);
      } else {
        $('.search-icon').click(inputEventFunction);
        input.addEventListener('keypress', function (event) {
          if (event.keyCode === 13) {
            inputEventFunction();
          }
        });
      }
      // remove loading animation
      $('body').css('overflow', '');
      proceedsearch();
    }
    // handle and trigger popup window;
    $('.popup-trigger').click(function (e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc('local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });
    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function (e) {
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 && $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });

    document.addEventListener('mouseup', (e) => {
      var _con = document.querySelector(".local-search-content");
      if (_con) {
        if (!_con.contains(e.target)) {
          onPopupClose();
        }
      }
    });
  </script>


		
	<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</body>
</html>
